package com.alan.wlmediaplayer.controller;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.SeekBar;

import androidx.annotation.Nullable;

import com.alan.wlmediaplayer.R;
import com.alan.wlmediaplayer.WlMediaPlayerLayout;
import com.alan.wlmediaplayer.databinding.WlMediaControllerBinding;
import com.alan.wlmediaplayer.databinding.WlMenuViewBinding;
import com.alan.wlmediaplayer.utils.WlSetting;
import com.alan.wlmediaplayer.utils.WlUtils;
import com.alan.wlmediaplayer.view.MenuView;
import com.alan.wlmediaplayer.view.WlDialog;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.lib.basex.dialog.bottom.BottomSheet;
import com.lib.basex.utils.Logger;
import com.lib.basex.widget.baselayout.LFrameLayout;

import java.util.Timer;
import java.util.TimerTask;

/**
 * @author Alan
 * 时 间：11/2/21
 * 简 述：<功能简述>
 */
public class WlMediaController extends LFrameLayout<String, WlMediaControllerBinding> implements SeekBar.OnSeekBarChangeListener, View.OnTouchListener {

    private WlMediaPlayerLayout mWlMediaPlayerLayout;

    private boolean mNeedChangePosition;
    private boolean mNeedChangeVolume;
    private boolean mNeedChangeBrightness;

    private long mGestureDownPosition;
    private float mGestureDownBrightness;
    private int mGestureDownVolume;
    private long mNewPosition;

    private float mDownX;
    private float mDownY;
    private static final int THRESHOLD = 80;

    private boolean isRefreshProgressEnable = true;

    public WlMediaController(Context context) {
        super(context);
    }

    public WlMediaController(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected int getContentId() {
        return R.layout.wl_media_controller;
    }

    public void onPlayStateChanged(int playState) {
        switch (playState) {
            case WlMediaPlayerLayout.STATE_IDLE:
                setPlayButtonState(false);
                break;
            case WlMediaPlayerLayout.STATE_COMPLETED:
                setPlayButtonState(false);
                setProgress(0, false);
                showInitState();
                break;
            case WlMediaPlayerLayout.STATE_ERROR:
                setPlayButtonState(false);
                showErrorLayout();
                break;
            case WlMediaPlayerLayout.STATE_DESTROY:
                setPlayButtonState(false);
                showInitState();
                break;
            case WlMediaPlayerLayout.STATE_PAUSED:
                setPlayButtonState(false);
                break;
            case WlMediaPlayerLayout.STATE_PLAYING:
                setPlayButtonState(true);
                hiddenLoadingStateView();
                break;
            case WlMediaPlayerLayout.STATE_PREPARED:
                setPlayButtonState(true);
                hiddenLoadingStateView();
                setAudioChannel();
                break;
            case WlMediaPlayerLayout.STATE_PREPARING:
//                setPlayButtonState(true);
//                break;
            case WlMediaPlayerLayout.STATE_CHANGING:
                showLoadingState();
                break;
        }
    }

    private void setAudioChannel() {
        String[] audioChannel = mWlMediaPlayerLayout.getAudioChannel();
        if (audioChannel != null && audioChannel.length > 0) {
            WlSetting.getInstance().setChannelData(audioChannel);
        }
    }

    @Override
    protected void initView(@Nullable AttributeSet attrs) {
        super.initView(attrs);
        d.controllerFrame.setOnTouchListener(this);
        WlSetting.getInstance().reset();
        d.loadingStateFrame.setOnClickListener(v -> {
        });
        d.restartOrPause.setOnClickListener(v -> mWlMediaPlayerLayout.start());
        d.seek.setOnSeekBarChangeListener(this);
        d.controllerFrame.setOnClickListener(v -> clickControllerFrame());
        d.centerStart.setOnClickListener(v -> clickCenterStart());
        d.fullScreen.setOnClickListener(v -> clickFullScreen());
        d.back.setOnClickListener(v -> clickBack());
        d.btnMenu.setOnClickListener(v -> clickMenu());
        setTopAndBottomVisible(false);
        d.errorStateFrame.setOnRetryListener(v -> {
            mWlMediaPlayerLayout.start();
            showLoadingState();
        });

    }


    public void setDefaultImage(String url, String tag) {
        d.image.get(url, tag);
    }


    private void clickMenu() {
        setTopAndBottomVisible(false);
        if (mWlMediaPlayerLayout.isFullScreen()) {
            showLandScapeMenuDialog();
        } else {
            showPortraitMenuDialog();
        }
    }

    public void clickBack() {
        if (mWlMediaPlayerLayout.isFullScreen()) {
            mWlMediaPlayerLayout.exitFullScreen();
        } else {
            ((Activity) getContext()).finish();
        }
    }

    private void clickFullScreen() {
        if (!mWlMediaPlayerLayout.isFullScreen()) {
            mWlMediaPlayerLayout.enterFullScreen();
        } else {
            mWlMediaPlayerLayout.exitFullScreen();
        }
    }

    private void clickCenterStart() {
        showLoadingState();
        mWlMediaPlayerLayout.start();
    }

    private void clickControllerFrame() {
        setTopAndBottomVisible(!(d.top.getVisibility() == View.VISIBLE));
    }

    public void setTitle(String name) {
        d.title.setText(name);
    }

    private void setTopAndBottomVisible(boolean isShow) {
        d.top.setVisibility(isShow ? View.VISIBLE : View.GONE);
        d.bottom.setVisibility(isShow ? View.VISIBLE : View.GONE);

    }

    public WlMediaController setMediaPlayerLayout(WlMediaPlayerLayout mWlMediaPlayerLayout) {
        this.mWlMediaPlayerLayout = mWlMediaPlayerLayout;
        return this;
    }

    private void setPlayButtonState(boolean isPlaying) {
        d.restartOrPause.setImageResource(!isPlaying ? R.drawable.ic_player_start : R.drawable.ic_player_pause);
    }

    public void setTotalTime(long time) {
        d.duration.setText(WlUtils.formatTime(time));
        d.seek.setMax((int) time);
    }

    public void setProgress(int progress, boolean isForce) {
        if (isRefreshProgressEnable || isForce) {
            d.seek.setProgress(progress);
            d.position.setText(WlUtils.formatTime(progress));
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        int progress = seekBar.getProgress();
        mWlMediaPlayerLayout.seek(progress);
    }

    private void showLoadingState() {
        setTopAndBottomVisible(false);
        d.loadingStateFrame.setVisibility(View.VISIBLE);
        d.centerStart.setVisibility(View.GONE);
        d.loading.setVisibility(View.VISIBLE);
        d.errorStateFrame.hidden();
    }

    private void showInitState() {
        d.loadingStateFrame.setVisibility(View.VISIBLE);
        setTopAndBottomVisible(false);
        d.centerStart.setVisibility(View.VISIBLE);
        d.loading.setVisibility(View.GONE);
        d.errorStateFrame.hidden();
    }

    private void hiddenLoadingStateView() {
        d.loadingStateFrame.setVisibility(View.GONE);
    }

    public void onPlayModeChanged(int playMode) {
        setTopAndBottomVisible(false);
//        switch (playMode) {
//            case WlMediaPlayerLayout.MODE_NORMAL:
//                setTopAndBottomVisible(false);
//                break;
//            case WlMediaPlayerLayout.MODE_FULL_SCREEN:
//                setTopAndBottomVisible(false);
//                break;
//        }
    }

    private void showPortraitMenuDialog() {
        BottomSheetDialog dialog = new BottomSheetDialog(getContext());
        MenuView menuView = new MenuView(getContext());
        menuView.setDialog(dialog);
        dialog.setContentView(menuView);
        dialog.show();
    }

    private void showLandScapeMenuDialog() {
        WlDialog dialog = new WlDialog(getContext());
        MenuView menuView = new MenuView(getContext());
        menuView.setDialog(dialog);
        dialog.setContentView(menuView);
        dialog.show();
    }

    private void showErrorLayout() {
        int errorCode = mWlMediaPlayerLayout.getErrorCode();
        String errorMsg = mWlMediaPlayerLayout.getErrorMsg();
        String msg = "code:" + errorCode + ";msg:" + errorMsg;
        d.errorStateFrame.show(msg);
        d.loadingStateFrame.setVisibility(View.GONE);
        setTopAndBottomVisible(false);
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Logger.d("onTouch");
        if (!mWlMediaPlayerLayout.isFullScreen()) {
            return false;
        }
        // 只有在播放、暂停、缓冲的时候能够拖动改变位置、亮度和声音
        if (!mWlMediaPlayerLayout.isPlaying()) {
            hideChangePosition();
            hideChangeBrightness();
            hideChangeVolume();
            return false;
        }

        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = x;
                mDownY = y;
                mNeedChangePosition = false;
                mNeedChangeVolume = false;
                mNeedChangeBrightness = false;
                break;
            case MotionEvent.ACTION_MOVE:
                float deltaX = x - mDownX;
                float deltaY = y - mDownY;
                float absDeltaX = Math.abs(deltaX);
                float absDeltaY = Math.abs(deltaY);
                if (!mNeedChangePosition && !mNeedChangeVolume && !mNeedChangeBrightness) {
                    // 只有在播放、暂停、缓冲的时候能够拖动改变位置、亮度和声音
                    if (absDeltaX >= THRESHOLD) {
                        cancelUpdateProgressTimer();
                        mNeedChangePosition = true;
                        mGestureDownPosition = mWlMediaPlayerLayout.getCurrentPosition();
                    } else if (absDeltaY >= THRESHOLD) {
                        if (mDownX < getWidth() * 0.5f) {
                            // 左侧改变亮度
                            mNeedChangeBrightness = true;
                            mGestureDownBrightness = WlUtils.scanForActivity(getContext())
                                    .getWindow().getAttributes().screenBrightness;
                        } else {
                            // 右侧改变声音
                            mNeedChangeVolume = true;
                            mGestureDownVolume = mWlMediaPlayerLayout.getVolume();
                        }
                    }
                }
                if (mNeedChangePosition) {
                    long duration = mWlMediaPlayerLayout.getDuration();
                    long toPosition = (long) (mGestureDownPosition + duration * deltaX / getWidth());
                    mNewPosition = Math.max(0, Math.min(duration, toPosition));
                    int newPositionProgress = (int) (100f * mNewPosition / duration);
                    showChangePosition(duration, newPositionProgress);
                }
                if (mNeedChangeBrightness) {
                    deltaY = -deltaY;
                    float deltaBrightness = deltaY * 3 / getHeight();
                    float newBrightness = mGestureDownBrightness + deltaBrightness;
                    newBrightness = Math.max(0, Math.min(newBrightness, 1));
                    float newBrightnessPercentage = newBrightness;
                    WindowManager.LayoutParams params = WlUtils.scanForActivity(getContext())
                            .getWindow().getAttributes();
                    params.screenBrightness = newBrightnessPercentage;
                    WlUtils.scanForActivity(getContext()).getWindow().setAttributes(params);
                    int newBrightnessProgress = (int) (100f * newBrightnessPercentage);
                    showChangeBrightness(newBrightnessProgress);
                }
                if (mNeedChangeVolume) {
                    deltaY = -deltaY;
                    int maxVolume = 100;
                    int deltaVolume = (int) (maxVolume * deltaY * 3 / getHeight());
                    int newVolume = mGestureDownVolume + deltaVolume;
                    newVolume = Math.max(0, Math.min(maxVolume, newVolume));
                    mWlMediaPlayerLayout.setVolume(newVolume);
                    int newVolumeProgress = (int) (100f * newVolume / maxVolume);
                    showChangeVolume(newVolumeProgress);
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (mNeedChangePosition) {
                    changePositionOnActionUp();
                    return true;
                }
                if (mNeedChangeBrightness) {
                    hideChangeBrightness();
                    return true;
                }
                if (mNeedChangeVolume) {
                    hideChangeVolume();
                    return true;
                }
                break;
        }

        return false;
    }

    protected void cancelUpdateProgressTimer() {
        isRefreshProgressEnable = false;
    }

    protected void startUpdateProgressTimer() {
        isRefreshProgressEnable = true;
    }

    protected void showChangePosition(long duration, int newPositionProgress) {
        d.changePosition.setVisibility(View.VISIBLE);
        int newPosition = (int) (duration * newPositionProgress / 100f);
        d.changePositionCurrent.setText(WlUtils.formatTime(newPosition));
        d.changePositionProgress.setProgress(newPositionProgress);
        setProgress(newPosition, true);
    }

    protected void hideChangePosition() {
        d.changePosition.setVisibility(View.GONE);
    }

    protected void showChangeVolume(int newVolumeProgress) {
        d.changeVolume.setVisibility(View.VISIBLE);
        d.changeVolumeProgress.setProgress(newVolumeProgress);
    }

    protected void hideChangeVolume() {
        d.changeVolume.setVisibility(View.GONE);
    }

    protected void showChangeBrightness(int newBrightnessProgress) {
        d.changeBrightness.setVisibility(View.VISIBLE);
        d.changeBrightnessProgress.setProgress(newBrightnessProgress);
    }

    protected void hideChangeBrightness() {
        d.changeBrightness.setVisibility(View.GONE);
    }

    protected void changePositionOnActionUp() {
        mWlMediaPlayerLayout.seek((int) mNewPosition);
        hideChangePosition();
        startUpdateProgressTimer();
    }

}
